

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/fluid.png">
  <link rel="icon" href="/img/fluid.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
    <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="dayu">
  <meta name="keywords" content="">
  
    <meta name="description" content="React 学习笔记类组件 Class Component一、React 简介React 是一个用于构建用户界面的 JavaScript 库，它是 Facebook 的内部项目，用来架设 Instagram 的网站，并于 2013 年 5 月开源。React 主要用于构建 UI，很多人认为 React 是 MVC 中的 V（视图）。由于拥有较高的性能，且代码逻辑非常简单，越来越多的人已开始关注和使">
<meta property="og:type" content="article">
<meta property="og:title" content="react学习笔记">
<meta property="og:url" content="http://dayu.com/2022/11/27/react%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/index.html">
<meta property="og:site_name" content="Dayu">
<meta property="og:description" content="React 学习笔记类组件 Class Component一、React 简介React 是一个用于构建用户界面的 JavaScript 库，它是 Facebook 的内部项目，用来架设 Instagram 的网站，并于 2013 年 5 月开源。React 主要用于构建 UI，很多人认为 React 是 MVC 中的 V（视图）。由于拥有较高的性能，且代码逻辑非常简单，越来越多的人已开始关注和使">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://files.catbox.moe/wmmkte.png">
<meta property="og:image" content="https://files.catbox.moe/wmmkte.png">
<meta property="article:published_time" content="2022-11-27T09:03:11.000Z">
<meta property="article:modified_time" content="2023-09-13T02:50:31.886Z">
<meta property="article:author" content="dayu">
<meta property="article:tag" content="react">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://files.catbox.moe/wmmkte.png">
  
  
    <meta name="referrer" content="no-referrer-when-downgrade">
  
  
  <title>react学习笔记 - Dayu</title>

  <link  rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css" />



  <link  rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css" />



<!-- 主题依赖的图标库，不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/css/main.css" />


  <link id="highlight-css" rel="stylesheet" href="/css/highlight.css" />
  
    <link id="highlight-css-dark" rel="stylesheet" href="/css/highlight-dark.css" />
  



  
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_3846514_kabxni94auf.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/bynotes/texiao/source/css/shubiao.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/bynotes/texiao/source/css/gundongtiao.css">



  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    Fluid.ctx = Object.assign({}, Fluid.ctx)
    var CONFIG = {"hostname":"dayu.com","root":"/","version":"1.9.3","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"right","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":true,"follow_dnt":true,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/local-search.xml"};

    if (CONFIG.web_analytics.follow_dnt) {
      var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
      Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
    }
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
  

  

  

  

  

  

  

  



  
<meta name="generator" content="Hexo 5.4.2"></head>


<body>
  

  <header>
    

<div class="header-inner" style="height: 70vh;">
  <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/">
      <strong>Dayu</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives">
                <i class="iconfont icon-books"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories">
                <i class="iconfont icon-th-large"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/links/">
                <i class="iconfont icon-link-fill"></i>
                友链
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" target="_self" href="javascript:;" role="button"
                 data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <i class="iconfont icon-book"></i>
                文档
              </a>
              <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://hexo.fluid-dev.com/">
                    
                    主题博客
                  </a>
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://hexo.fluid-dev.com/docs/guide/">
                    
                    配置指南
                  </a>
                
                  
                  
                  
                  <a class="dropdown-item" target="_blank" rel="noopener" href="https://hexo.fluid-dev.com/docs/icon/">
                    
                    图标用法
                  </a>
                
              </div>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              &nbsp;<i class="iconfont icon-search"></i>&nbsp;
            </a>
          </li>
          
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

  

<div id="banner" class="banner" parallax=true
     style="background: url('/img/default.png') no-repeat center center; background-size: cover;">
  <div class="full-bg-img">
    <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
      <div class="banner-text text-center fade-in-up">
        <div class="h2">
          
            <span id="subtitle" data-typed-text="react学习笔记"></span>
          
        </div>

        
          
  <div class="mt-3">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-author" aria-hidden="true"></i>
        dayu
      </span>
    
    
      <span class="post-meta">
        <i class="iconfont icon-date-fill" aria-hidden="true"></i>
        <time datetime="2022-11-27 17:03" pubdate>
           2022 年 11 月 27 日 , 下午 05:03 , 星期日
        </time>
      </span>
    
  </div>

  <div class="mt-1">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-chart"></i>
        
          <!-- compatible with older versions-->
          23k 字
        
      </span>
    

    
      <span class="post-meta mr-2">
        <i class="iconfont icon-clock-fill"></i>
        
        
        
          <!-- compatible with older versions-->
          194 分钟
        
      </span>
    

    
    
  </div>


        
      </div>

      
    </div>
  </div>
</div>

</div>

  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="side-col d-none d-lg-block col-lg-2">
      

    </div>

    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">react学习笔记</h1>
            
            
              <div class="markdown-body">
                
                <h1 id="React-学习笔记"><a href="#React-学习笔记" class="headerlink" title="React 学习笔记"></a>React 学习笔记</h1><h2 id="类组件-Class-Component"><a href="#类组件-Class-Component" class="headerlink" title="类组件 Class Component"></a>类组件 Class Component</h2><h3 id="一、React-简介"><a href="#一、React-简介" class="headerlink" title="一、React 简介"></a>一、React 简介</h3><p>React 是一个用于构建用户界面的 JavaScript 库，它是 Facebook 的内部项目，用来架设 Instagram 的网站，并于 2013 年 5 月开源。React 主要用于构建 UI，很多人认为 React 是 MVC 中的 V（视图）。由于拥有较高的性能，且代码逻辑非常简单，越来越多的人已开始关注和使用它。</p>
<h3 id="二、React-特点"><a href="#二、React-特点" class="headerlink" title="二、React 特点"></a>二、React 特点</h3><h4 id="1、声明式设计"><a href="#1、声明式设计" class="headerlink" title="1、声明式设计"></a>1、声明式设计</h4><p>react 是面向数据编程，不需要直接去控制 dom，你只要把数据操作好，react 自己会去帮你操作 dom，可以节省很多操作 dom 的代码。这就是声明式开发。</p>
<h4 id="2、使用-JSX-语法"><a href="#2、使用-JSX-语法" class="headerlink" title="2、使用 JSX 语法"></a>2、使用 JSX 语法</h4><p>JSX 是 JavaScript 语法的扩展。React 开发大部分使用 JSX 语法（在 JSX 中可以将 HTML 于 JS 混写）。</p>
<h4 id="3、灵活"><a href="#3、灵活" class="headerlink" title="3、灵活"></a>3、灵活</h4><p>react 所控制的 dom 就是 id 为 root 的 dom，页面上的其他 dom 元素你页可以使用 jq 等其他框架 。可以和其他库并存。</p>
<h4 id="4、使用虚拟-DOM、高效"><a href="#4、使用虚拟-DOM、高效" class="headerlink" title="4、使用虚拟 DOM、高效"></a>4、使用虚拟 DOM、高效</h4><p>虚拟 DOM 其实质是一个 JavaScript 对象，当数据和状态发生了变化，都会被自动高效的同步到虚拟 DOM 中，最后再将仅变化的部分同步到 DOM 中（不需要整个 DOM 树重新渲染）。</p>
<h4 id="5、组件化开发"><a href="#5、组件化开发" class="headerlink" title="5、组件化开发"></a>5、组件化开发</h4><p>通过 React 构建组件，使得代码更加容易得到复用和维护，能够很好的应用在大项目的开发中。</p>
<h4 id="6、单向数据流"><a href="#6、单向数据流" class="headerlink" title="6、单向数据流"></a>6、单向数据流</h4><p>react 是单向数据流，父组件传递给子组件的数据，子组件能够使用，但是不能直接通过 this.props 修改。 这样让数据清晰代码容易维护。</p>
<h3 id="三、创建-React-脚手架项目"><a href="#三、创建-React-脚手架项目" class="headerlink" title="三、创建 React 脚手架项目"></a>三、创建 React 脚手架项目</h3><figure class="highlight dsconfig"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs dsconfig"><span class="hljs-string">npx</span> <span class="hljs-built_in">create-react-app</span> <span class="hljs-string">demo</span><br></code></pre></td></tr></table></figure>

<p><code>注意：项目路径不能有中文，不能有怪异符号，包括“!”也不行！！！！</code></p>
<figure class="highlight dos"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs dos"><span class="hljs-built_in">cd</span> demo<br>yarn <span class="hljs-built_in">start</span><br></code></pre></td></tr></table></figure>

<h3 id="四、hello-world-程序编写"><a href="#四、hello-world-程序编写" class="headerlink" title="四、hello_world 程序编写"></a>四、hello_world 程序编写</h3><ul>
<li>删除在 src 目录下所有文件</li>
<li>src 目录下新建 index.js 文件作为入口文件</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">//1、引入React两个核心模块</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">ReactDOM</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-dom&#x27;</span><br><br><span class="hljs-comment">//2、通过JSX语法将组件/标签渲染到指定标签上</span><br><span class="hljs-title class_">ReactDOM</span>.<span class="hljs-title function_">render</span>(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>hello world!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>, <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;root&#x27;</span>))<br></code></pre></td></tr></table></figure>

<p>ReactDOM.render(参数 1，参数 2)</p>
<p>参数 1 是 JSX 语法的标签/组件</p>
<p>参数 2 是要把参数 1 这个标签渲染到的位置</p>
<h3 id="五、VSCode-中-JSX-的编写优化"><a href="#五、VSCode-中-JSX-的编写优化" class="headerlink" title="五、VSCode 中 JSX 的编写优化"></a>五、VSCode 中 JSX 的编写优化</h3><p>在 vscode 中的 <code>文件&gt;首选项&gt;设置</code> 中，直接搜索 <code>include Language</code> ，进入 <code>settings.json</code> ：</p>
<p>找到 <code>&quot;emmet.includeLanguages&quot;</code> 字段，添加：</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs json"><span class="hljs-attr">&quot;emmet.includeLanguages&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">&#123;</span><br>  <span class="hljs-attr">&quot;javascript&quot;</span><span class="hljs-punctuation">:</span> <span class="hljs-string">&quot;javascriptreact&quot;</span><br><span class="hljs-punctuation">&#125;</span><br></code></pre></td></tr></table></figure>

<p>搜索 <code>trigger</code> ，勾选 <code>Trigger Expansion On Tab</code> (设置后就可以通过 标签名+Tab 键快速码出标签)</p>
<h3 id="六、组件化开发"><a href="#六、组件化开发" class="headerlink" title="六、组件化开发"></a>六、组件化开发</h3><p>在 React 的项目中，都是使用组件化开发的模式，所以，我们可以把刚才的 hello world 的 h1 定义为一个组件：</p>
<p>定义组件分为 3 步：</p>
<p>1、导入 React 核心模块</p>
<p>2、定义组件类</p>
<p>3、导出组件</p>
<p>在 src 目录下新建 App.js 文件：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">//1、导入React核心模块</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-comment">//2、定义组件类</span><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Hello</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">React.Component</span> &#123;<br>  <span class="hljs-comment">//类</span><br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">//函数</span><br>    <span class="hljs-keyword">return</span> (<br>      <span class="hljs-comment">//返回值</span><br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>hello world !!! 我是组件222<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br><span class="hljs-comment">//3、导出组件</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">Hello</span><br></code></pre></td></tr></table></figure>

<p>在需要引入该组件的 index.js 中，导入，就可以直接使用这个组件了：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">//import 组件名 from &#x27;文件路径&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">Hello</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./App&#x27;</span> <span class="hljs-comment">//1、导入Hello组件  (首字母必须大写)</span><br><br><span class="hljs-title class_">ReactDOM</span>.<span class="hljs-title function_">render</span>(<br>  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Hello</span> /&gt;</span></span>, <span class="hljs-comment">// 2、使用Hello组件  (首字母必须大写)</span><br>  <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;root&#x27;</span>)<br>)<br><br><span class="hljs-comment">//注意：Hello是组件名，在使用的时候就应该写JSX标签写法，而不能直接写Hello</span><br></code></pre></td></tr></table></figure>

<p><strong>！！注意：</strong></p>
<p><strong>1、定义组件的时候，return 后面只能有一个根标签，不能有多个，但这个标签内部可以有其他多个标签</strong></p>
<p><strong>2、使用组件的时候，首字母必须大写</strong></p>
<p><strong>3、如果最外层实在不想放置一层 div 根目录，可以使用 <code>&lt;&gt;</code> 空标签代替</strong></p>
<h3 id="七、JSX-语法糖"><a href="#七、JSX-语法糖" class="headerlink" title="七、JSX 语法糖"></a>七、JSX 语法糖</h3><p>React 使用 JSX 来替代常规的 JavaScript。JSX 是一个看起来很像 XML 的 JavaScript 语法扩展，在 React 中会被 babel 编译为 JavaScript。</p>
<h4 id="1、JSX-的特点"><a href="#1、JSX-的特点" class="headerlink" title="1、JSX 的特点"></a>1、JSX 的特点</h4><ul>
<li>JSX 执行更快，因为它在编译为 JavaScript 代码后进行了优化。</li>
<li>它是类型安全的，在编译过程中就能发现错误。</li>
<li>使用 JSX 编写模板更加简单快速。</li>
</ul>
<h4 id="2、JSX-几个注意的格式："><a href="#2、JSX-几个注意的格式：" class="headerlink" title="2、JSX 几个注意的格式："></a>2、JSX 几个注意的格式：</h4><p>1、React 的 JSX 是使用大写和小写字母来区分本地组件和 HTML 组件</p>
<p>（如：html 就用 div p h1 ， 组件就用 MyButton App Home List 等 ）</p>
<p>2、JSX 和 html 的标签属性的区别</p>
<ul>
<li><p>for—htmlFor—for 在 JS 中为 for 循环关键字</p>
</li>
<li><p>class—className—class 在 JS 中为声明类关键字</p>
</li>
<li><p>style—需使用 JS 对象(使用双花括号)</p>
</li>
</ul>
<p>组件中：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; <span class="hljs-title class_">Component</span> &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">var</span> <span class="hljs-title class_">MyImg</span> = <span class="hljs-built_in">require</span>(<span class="hljs-string">&#x27;./assets/01.jpg&#x27;</span>)<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">App2</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Component</span> &#123;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">htmlFor</span>=<span class="hljs-string">&quot;ipt&quot;</span>&gt;</span>label<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">input</span></span></span><br><span class="hljs-tag"><span class="language-xml">          <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span></span></span><br><span class="hljs-tag"><span class="language-xml">          <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;ipt&quot;</span></span></span><br><span class="hljs-tag"><span class="language-xml">          <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;ipt&quot;</span></span></span><br><span class="hljs-tag"><span class="language-xml">          <span class="hljs-attr">style</span>=<span class="hljs-string">&#123;&#123;</span> <span class="hljs-attr">background:</span> &#x27;<span class="hljs-attr">pink</span>&#x27;, <span class="hljs-attr">color:</span> &#x27;<span class="hljs-attr">green</span>&#x27; &#125;&#125;</span></span><br><span class="hljs-tag"><span class="language-xml">        /&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">hr</span> /&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&#123;MyImg&#125;</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">&quot;&quot;</span> /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>注意：图片查找路径在 src 目录，所以引入的时候从 src 目录触发查找文件</p>
<h4 id="3、React-的-JSX-创建出来的是虚拟-DOM，而不是-HTML"><a href="#3、React-的-JSX-创建出来的是虚拟-DOM，而不是-HTML" class="headerlink" title="3、React 的 JSX 创建出来的是虚拟 DOM，而不是 HTML"></a>3、React 的 JSX 创建出来的是虚拟 DOM，而不是 HTML</h4><p>在 index.js 中：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">ReactDOM</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-dom&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./App3&#x27;</span><br><br><span class="hljs-title class_">ReactDOM</span>.<span class="hljs-title function_">render</span>(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span>, <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;root&#x27;</span>))<br><br><span class="hljs-keyword">const</span> virtualDOM = <span class="hljs-title class_">React</span>.<span class="hljs-title function_">createElement</span>(<span class="hljs-string">&#x27;div&#x27;</span>)<br><span class="hljs-keyword">const</span> realDOM = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">createElement</span>(<span class="hljs-string">&#x27;div&#x27;</span>)<br><br><span class="hljs-keyword">let</span> virtualNum = <span class="hljs-number">0</span><br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> key <span class="hljs-keyword">in</span> virtualDOM) &#123;<br>  virtualNum++<br>&#125;<br><br><span class="hljs-keyword">let</span> realNum = <span class="hljs-number">0</span><br><span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> key <span class="hljs-keyword">in</span> realDOM) &#123;<br>  realNum++<br>&#125;<br><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;虚拟DOM的属性个数：&#x27;</span> + virtualNum) <span class="hljs-comment">// 7</span><br><span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;真实DOM的属性个数：&#x27;</span> + realNum) <span class="hljs-comment">// 298</span><br></code></pre></td></tr></table></figure>

<h4 id="4、JSX-变量引用、三目运算符、for-循环"><a href="#4、JSX-变量引用、三目运算符、for-循环" class="headerlink" title="4、JSX 变量引用、三目运算符、for 循环"></a>4、JSX 变量引用、三目运算符、for 循环</h4><p>在 JSX 中，想要调用变量，需要在 return 中直接使用单花括号–**{}**调用</p>
<p>index.js 中：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">//第四节：JSX中变量引用、三目运算符、for循环的使用</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">App3</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./App3&#x27;</span><br><br><span class="hljs-comment">//2、通过JSX语法将标签/组件渲染到指定标签上</span><br><span class="hljs-title class_">ReactDOM</span>.<span class="hljs-title function_">render</span>(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">App3</span> /&gt;</span></span>, <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;root&#x27;</span>))<br></code></pre></td></tr></table></figure>

<p>App3.js 中：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; <span class="hljs-title class_">Component</span> &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">let</span> name = <span class="hljs-string">&#x27;小明&#x27;</span>,<br>  num1 = <span class="hljs-number">20</span>,<br>  num2 = <span class="hljs-number">30</span>,<br>  arr = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>]<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">App3</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Component</span> &#123;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        &#123;/* 这是注释的格式 */&#125;</span><br><span class="language-xml">        &#123;/* JSX中引用变量需要加单花括号 */&#125;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>&#123;name&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml"></span><br><span class="language-xml">        &#123;/* 三目运算符的使用 */&#125;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>num1和num2中比较大的是：&#123;num1 &gt; num2 ? num1 : num2&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>&#123;gender === 0 ? &#x27;男&#x27; : gender === 1 ? &#x27;女&#x27; : &#x27;保密&#x27;&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span></span><br><span class="language-xml"></span><br><span class="language-xml">        &#123;/* for循环的使用 */&#125;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span></span><br><span class="language-xml">          &#123;/* 数组名.map(函数) */&#125;</span><br><span class="language-xml">          &#123;</span><br><span class="language-xml">            //格式1：</span><br><span class="language-xml">            arr.map((v, k) =&gt; (</span><br><span class="language-xml">              <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">&#123;k&#125;</span>&gt;</span>&#123;v&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml">            ))</span><br><span class="language-xml">          &#125;</span><br><span class="language-xml">          &#123;</span><br><span class="language-xml">            //格式2：可以把下面的大括号和return换成小括号</span><br><span class="language-xml">            arr.map((v, k) =&gt; &#123;</span><br><span class="language-xml">              return <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">&#123;k&#125;</span>&gt;</span>&#123;v&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml">            &#125;)</span><br><span class="language-xml">          &#125;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p><strong>总结：在 jsx 语法中，需要书写 js 代码的时候，请先加上{ } 再书写 js 语法</strong></p>
<h3 id="八、VSCode-中，代码片段扩展的安装"><a href="#八、VSCode-中，代码片段扩展的安装" class="headerlink" title="八、VSCode 中，代码片段扩展的安装"></a>八、VSCode 中，代码片段扩展的安装</h3><p>安装 ES7 React/Redux/GraphQL/React-Native snippets</p>
<p>输入 rcc 或 rfc 可快速得到组件的代码片段</p>
<h3 id="九、事件、state-与-setState"><a href="#九、事件、state-与-setState" class="headerlink" title="九、事件、state 与 setState"></a>九、事件、state 与 setState</h3><p>App5.js 中:</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">//事件讲解</span><br><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; <span class="hljs-title class_">Component</span> &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-comment">//1、实现点击弹框效果(事件基本格式)</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">App5</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Component</span> &#123;<br>    <span class="hljs-title function_">handleClick</span>(<span class="hljs-params"></span>)&#123;<br>        <span class="hljs-title function_">alert</span>(<span class="hljs-number">132456</span>)<br>    &#125;<br><br>    <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>        <span class="hljs-keyword">return</span> (<br>            <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;this.handleClick&#125;</span>&gt;</span>按钮<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>        )<br>    &#125;<br>&#125;<br><br><br><span class="hljs-comment">//2、实现累加的功能 (状态的使用1)</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">App4</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Component</span> &#123;<br>    <span class="hljs-title function_">constructor</span>(<span class="hljs-params">props</span>)&#123;<br>        <span class="hljs-variable language_">super</span>(props)<br>        <span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span> = &#123;<br>            <span class="hljs-attr">num</span>: <span class="hljs-number">0</span><br>        &#125;<br>        <span class="hljs-comment">// 按钮3的函数写法的前提</span><br>        <span class="hljs-variable language_">this</span>.<span class="hljs-property">handleClick</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">handleClick</span>.<span class="hljs-title function_">bind</span>(<span class="hljs-variable language_">this</span>);<br>    &#125;<br>    <span class="hljs-title function_">handleClick</span>(<span class="hljs-params"></span>)&#123;<br>        <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setState</span>(&#123;<br>            <span class="hljs-attr">num</span>: <span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">num</span>+<span class="hljs-number">1</span><br>        &#125;)<br>    &#125;<br>    <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>        <span class="hljs-keyword">return</span> (<br>            <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">                <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>&#123; this.state.num &#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br><span class="language-xml">                &#123;/* 通过bind来改变this的指向 */&#125;</span><br><span class="language-xml">                &#123;/* <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;this.handleClick.bind(this)&#125;</span>&gt;</span>按钮1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> */&#125;</span><br><span class="language-xml">                &#123;/* 箭头函数默认没有this，所以this指向数组对象 */&#125;</span><br><span class="language-xml">                &#123;/* <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span>=&gt;</span>this.handleClick()&#125;&gt;按钮2<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> */&#125;</span><br><span class="language-xml">                <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;this.handleClick&#125;</span>&gt;</span>按钮3<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>        )<br>    &#125;<br>&#125;<br><br><br><span class="hljs-comment">//3、实现双向数据绑定 (状态的使用2)</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">App5</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Component</span> &#123;<br>    <span class="hljs-title function_">constructor</span>(<span class="hljs-params">p</span>)&#123;<br>        <span class="hljs-variable language_">super</span>(p)<br>        <span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span> = &#123;<br>            <span class="hljs-attr">name</span>: <span class="hljs-string">&quot;你好，世界&quot;</span><br>        &#125;<br>    &#125;<br>    <span class="hljs-title function_">handleChange</span>(<span class="hljs-params">e</span>)&#123;<br>        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(e.<span class="hljs-property">currentTarget</span>.<span class="hljs-property">value</span>)<br>        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(e.<span class="hljs-property">target</span>.<span class="hljs-property">value</span>)<br>        <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setState</span>(&#123;<br>            <span class="hljs-attr">name</span>: e.<span class="hljs-property">target</span>.<span class="hljs-property">value</span><br>        &#125;)<br>    &#125;<br>    <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>        <span class="hljs-keyword">return</span> (<br>            <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">                <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>&#123; this.state.name &#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br><span class="language-xml">                <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&#123;this.state.name&#125;</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">&#123;this.handleChange.bind(this)&#125;</span> /&gt;</span></span><br><span class="language-xml">            <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>        )<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="十、state-的简写"><a href="#十、state-的简写" class="headerlink" title="十、state 的简写"></a>十、state 的简写</h3><p>App6.js 中：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; <span class="hljs-title class_">Component</span> &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">App6</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Component</span> &#123;<br>  <span class="hljs-comment">// 写在construtor中的state也可以简写</span><br>  state = &#123;<br>    <span class="hljs-attr">username</span>: <span class="hljs-string">&#x27;张三&#x27;</span>,<br>  &#125;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>&#123;this.state.username&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;this.handleClick.bind(this)&#125;</span>&gt;</span>按钮<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>  <span class="hljs-title function_">handleClick</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setState</span>(&#123;<br>      <span class="hljs-attr">username</span>: <span class="hljs-string">&#x27;李四&#x27;</span>,<br>    &#125;)<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="十一、累加"><a href="#十一、累加" class="headerlink" title="十一、累加"></a>十一、累加</h3><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; <span class="hljs-title class_">Component</span> &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">App7</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Component</span> &#123;<br>  state = &#123;<br>    <span class="hljs-attr">num</span>: <span class="hljs-number">0</span>,<br>  &#125;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">style</span>=<span class="hljs-string">&#123;&#123;</span> <span class="hljs-attr">textAlign:</span> &#x27;<span class="hljs-attr">center</span>&#x27; &#125;&#125;&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>&#123;this.state.num&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;this.addNum.bind(this)&#125;</span>&gt;</span>累加<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>  <span class="hljs-comment">// 累加</span><br>  <span class="hljs-title function_">addNum</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">// num++ (num = num + 1) num++是会修改num的</span><br>    <span class="hljs-comment">// this.state.num++      this.state.num被修改了</span><br>    <span class="hljs-comment">// 唯一能修改state的方法是setState</span><br>    <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setState</span>(&#123;<br>      <span class="hljs-attr">num</span>: <span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">num</span> + <span class="hljs-number">1</span>,<br>    &#125;)<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>这里考点在于 <code>++</code> 会修改原数据，而在 react 中，修改 state 中的数据必须通过 setState，因此这里不能对 <code>this.state.num</code> 直接进行 <code>++</code> 操作。</p>
<h3 id="十二、state-中数组的修改"><a href="#十二、state-中数组的修改" class="headerlink" title="十二、state 中数组的修改"></a>十二、state 中数组的修改</h3><p>我们对数组进行操作时，大部分数组方法会修改到原数组，因此建议先将数组深拷贝一次，修改后再重新赋值：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; <span class="hljs-title class_">Component</span> &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">App9</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Component</span> &#123;<br>  state = &#123;<br>    <span class="hljs-attr">arr</span>: [<span class="hljs-string">&#x27;张飞&#x27;</span>, <span class="hljs-string">&#x27;赵云&#x27;</span>, <span class="hljs-string">&#x27;刘备&#x27;</span>],<br>  &#125;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span></span><br><span class="language-xml">          &#123;this.state.arr.map((item, index) =&gt; &#123;</span><br><span class="language-xml">            return <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">&#123;index&#125;</span>&gt;</span>&#123;item&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml">          &#125;)&#125;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;this.addFn.bind(this)&#125;</span>&gt;</span>追加一项到arr的最后<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>  <span class="hljs-comment">// 追加一项到arr的最后</span><br>  <span class="hljs-comment">// 修改state的方式只能是setState</span><br>  <span class="hljs-comment">// 数组的push方法会修改原数组</span><br>  <span class="hljs-comment">// this.state.arr.push() 会造成直接修改了state中的arr</span><br>  <span class="hljs-comment">// 修改数组，不能直接修改this.state.arr</span><br><br>  <span class="hljs-title function_">addFn</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-comment">// 如果我声明一个变量，等于this.state.arr，并且让这个变量和this.state.arr完全脱离关系[深拷贝]</span><br>    <span class="hljs-keyword">let</span> newArr = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(<span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">state</span>.<span class="hljs-property">arr</span>))<br>    <span class="hljs-comment">// 往newArr中push一项</span><br>    newArr.<span class="hljs-title function_">push</span>(<span class="hljs-string">&#x27;关羽&#x27;</span>)<br>    <span class="hljs-comment">// 把最新的newArr赋值给arr</span><br>    <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setState</span>(&#123;<br>      <span class="hljs-attr">arr</span>: newArr,<br>    &#125;)<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="十三、案例：Tab-栏"><a href="#十三、案例：Tab-栏" class="headerlink" title="十三、案例：Tab 栏"></a>十三、案例：Tab 栏</h3><p>App7.js 中：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; <span class="hljs-title class_">Component</span> &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-string">&#x27;./com.css&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">App7</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_ inherited__">Component</span> &#123;<br>  state = &#123;<br>    <span class="hljs-attr">arr</span>: [<span class="hljs-string">&#x27;新闻&#x27;</span>, <span class="hljs-string">&#x27;体育&#x27;</span>, <span class="hljs-string">&#x27;知识&#x27;</span>],<br>    <span class="hljs-attr">activeNum</span>: <span class="hljs-number">0</span>,<br>  &#125;<br>  <span class="hljs-title function_">render</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">&quot;banner&quot;</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span></span><br><span class="language-xml">          &#123;this.state.arr.map((item, index) =&gt; &#123;</span><br><span class="language-xml">            // this.handleClick.bind(this, 参数)</span><br><span class="language-xml">            return (</span><br><span class="language-xml">              <span class="hljs-tag">&lt;<span class="hljs-name">li</span></span></span><br><span class="hljs-tag"><span class="language-xml">                <span class="hljs-attr">key</span>=<span class="hljs-string">&#123;index&#125;</span></span></span><br><span class="hljs-tag"><span class="language-xml">                <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;this.handleClick.bind(this,</span> <span class="hljs-attr">index</span>)&#125;</span></span><br><span class="hljs-tag"><span class="language-xml">                <span class="hljs-attr">className</span>=<span class="hljs-string">&#123;this.state.activeNum</span> == <span class="hljs-string">index</span> ? &#x27;<span class="hljs-attr">active</span>&#x27; <span class="hljs-attr">:</span> &#x27;&#x27;&#125;&gt;</span></span><br><span class="language-xml">                &#123;item&#125;</span><br><span class="language-xml">              <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml">            )</span><br><span class="language-xml">          &#125;)&#125;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">ol</span>&gt;</span></span><br><span class="language-xml">          &#123;this.state.arr.map((item, index) =&gt; &#123;</span><br><span class="language-xml">            return (</span><br><span class="language-xml">              <span class="hljs-tag">&lt;<span class="hljs-name">li</span></span></span><br><span class="hljs-tag"><span class="language-xml">                <span class="hljs-attr">key</span>=<span class="hljs-string">&#123;index&#125;</span></span></span><br><span class="hljs-tag"><span class="language-xml">                <span class="hljs-attr">className</span>=<span class="hljs-string">&#123;this.state.activeNum</span> == <span class="hljs-string">index</span> ? &#x27;<span class="hljs-attr">active</span>&#x27; <span class="hljs-attr">:</span> &#x27;&#x27;&#125;&gt;</span></span><br><span class="language-xml">                &#123;item&#125;</span><br><span class="language-xml">              <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml">            )</span><br><span class="language-xml">          &#125;)&#125;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">ol</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>    )<br>  &#125;<br>  <span class="hljs-title function_">handleClick</span>(<span class="hljs-params">index</span>) &#123;<br>    <span class="hljs-comment">// console.log(index)  // 得到索引值</span><br>    <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setState</span>(&#123;<br>      <span class="hljs-attr">activeNum</span>: index,<br>    &#125;)<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure>

<p>com.css 中：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><code class="hljs jsx">*&#123;<span class="hljs-attr">margin</span>: <span class="hljs-number">0</span>;<span class="hljs-attr">padding</span>: <span class="hljs-number">0</span>;<span class="hljs-attr">border</span>: <span class="hljs-number">0</span>;list-<span class="hljs-attr">style</span>: none;&#125;<br><br>.<span class="hljs-property">banner</span>&#123;<br>    <span class="hljs-attr">width</span>: 500px;<br>    <span class="hljs-attr">height</span>: 300px;<br>    <span class="hljs-attr">margin</span>: 100px auto;<br>    <span class="hljs-attr">border</span>: 1px solid #<span class="hljs-number">000</span>;<br>&#125;<br><br>ul&#123;<br>    <span class="hljs-attr">height</span>: 60px;<br>    line-<span class="hljs-attr">height</span>: 60px;<br>    <span class="hljs-attr">display</span>: flex;<br>    text-<span class="hljs-attr">align</span>: center;<br>    justify-<span class="hljs-attr">content</span>: space-between;<br>&#125;<br><br>ul li&#123;<br>    <span class="hljs-attr">height</span>: 60px;<br>    <span class="hljs-attr">width</span>: <span class="hljs-number">30</span>%;<br>    <span class="hljs-attr">background</span>: #efefef;<br>&#125;<br><br>ul li.<span class="hljs-property">active</span>&#123;<br>    <span class="hljs-attr">background</span>: darkred;<br>    <span class="hljs-attr">color</span>: #fff;<br>&#125;<br><br>ol li&#123;<br>    <span class="hljs-attr">height</span>: 240px;<br>    <span class="hljs-attr">background</span>: darkred;<br>    text-<span class="hljs-attr">align</span>: center;<br>    line-<span class="hljs-attr">height</span>: 240px;<br>    <span class="hljs-attr">color</span>: #fff;<br>    <span class="hljs-attr">display</span>: none;<br>&#125;<br><br>ol li.<span class="hljs-property">active</span>&#123;<br>    <span class="hljs-attr">display</span>: block;<br>&#125;<br></code></pre></td></tr></table></figure>

<h2 id="函数式组件-Function-Component"><a href="#函数式组件-Function-Component" class="headerlink" title="函数式组件 Function Component"></a>函数式组件 Function Component</h2><h3 id="一、函数式组件"><a href="#一、函数式组件" class="headerlink" title="一、函数式组件"></a>一、函数式组件</h3><figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// App.jsx</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>你好世界<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>

<ul>
<li>没有 this，组件中打印 this，会得到 undefined</li>
<li>没有 state，数据的控制不受 state 管理，需要使用 hooks</li>
<li>没有生命周期</li>
</ul>
<p><img src="https://files.catbox.moe/wmmkte.png" srcset="/img/loading.gif" lazyload alt="Class Component的生命周期"></p>
<h3 id="二、父子传参"><a href="#二、父子传参" class="headerlink" title="二、父子传参"></a>二、父子传参</h3><h4 id="1、父传子"><a href="#1、父传子" class="headerlink" title="1、父传子"></a>1、父传子</h4><p>父组件以属性形式将值传递给子组件即可：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// 父组件</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">Sub</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./Sub&#x27;</span><br><br><span class="hljs-keyword">let</span> msg = <span class="hljs-string">&quot;你好世界&quot;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>)&#123;<br>    <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Sub</span> <span class="hljs-attr">msg</span>=<span class="hljs-string">&#123;msg&#125;</span> /&gt;</span></span><br>&#125;<br><br><span class="hljs-comment">// 子组件</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">Sub</span>(<span class="hljs-params">props</span>) &#123;<br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>&#123;props.msg&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="2、子传父"><a href="#2、子传父" class="headerlink" title="2、子传父"></a>2、子传父</h4><p>子传父的本质是父组件创建好方法，然后传递到子组件调用：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// 父组件</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">Sub</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./Sub&#x27;</span><br><span class="hljs-keyword">let</span> msg = <span class="hljs-string">&quot;你好世界&quot;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>)&#123;<br>    <span class="hljs-keyword">const</span> fn = <span class="hljs-keyword">function</span>(<span class="hljs-params">arg</span>)&#123;<br>        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(arg)	<span class="hljs-comment">// 123</span><br>    &#125;<br>    <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Sub</span> <span class="hljs-attr">msg</span>=<span class="hljs-string">&#123;msg&#125;</span> <span class="hljs-attr">fn</span>=<span class="hljs-string">&#123;fn&#125;</span>  /&gt;</span></span><br>&#125;<br><br><span class="hljs-comment">// 子组件</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">Sub</span>(<span class="hljs-params">props</span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>      <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>&#123;props.msg&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span>=&gt;</span>props.fn(123)&#125;&gt;将123传递给父组件<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="三、Hooks"><a href="#三、Hooks" class="headerlink" title="三、Hooks"></a>三、Hooks</h3><p>由于 Function Component 的以上特点，导致最初函数式组件并未受到开发者青睐。随着 React 推出 Hooks，函数式组件已是未来的 React 开发趋势。</p>
<h4 id="1、useState"><a href="#1、useState" class="headerlink" title="1、useState"></a>1、useState</h4><p>定义响应式的数据可以使用 useState，此处实现一个累加：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> [num, setNum] = <span class="hljs-title class_">React</span>.<span class="hljs-title function_">useState</span>(<span class="hljs-number">1</span>)<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>数字为：&#123;num&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> setNum(num + 1)&#125;&gt;累加<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>

<p>而实际上，React.useState 可以解构使用：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123;useState&#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>)&#123;<br>	<span class="hljs-keyword">const</span> [num, setNum] = <span class="hljs-title function_">useState</span>(<span class="hljs-number">1</span>)<br>	....<br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="2、useEffect"><a href="#2、useEffect" class="headerlink" title="2、useEffect"></a>2、useEffect</h4><p>有时我们需要在挂载后请求数据、销毁前清除数据，或是在更新后获取数据，那么就需要借助 useEffect。</p>
<h5 id="（模拟）挂载后"><a href="#（模拟）挂载后" class="headerlink" title="（模拟）挂载后"></a>（模拟）挂载后</h5><p>一般在挂载后做数据请求：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; useEffect &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-title function_">useEffect</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-comment">// do some requests</span><br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;挂载后&#x27;</span>)<br>  &#125;)<br><br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>你好世界<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br>&#125;<br></code></pre></td></tr></table></figure>

<h5 id="（模拟）销毁前"><a href="#（模拟）销毁前" class="headerlink" title="（模拟）销毁前"></a>（模拟）销毁前</h5><p>一般在这个阶段做垃圾回收或数据清理：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; useEffect &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-title function_">useEffect</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-comment">// do some requests</span><br>    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> &#123;<br>      <span class="hljs-comment">// do some clear</span><br>      <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;销毁前&#x27;</span>)<br>    &#125;<br>  &#125;)<br><br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>你好世界<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br>&#125;<br></code></pre></td></tr></table></figure>

<p>在 useEffect 的 callback 中返回一个函数，代表“销毁前”。如果想要体验销毁前，可以在入口文件 index.js 中添加：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>  <span class="hljs-title class_">ReactDOM</span>.<span class="hljs-title function_">render</span>(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> /&gt;</span></span>, <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;root&#x27;</span>))<br>&#125;, <span class="hljs-number">3000</span>)<br></code></pre></td></tr></table></figure>

<h5 id="（模拟）检测更新"><a href="#（模拟）检测更新" class="headerlink" title="（模拟）检测更新"></a>（模拟）检测更新</h5><p>useEffect 这个钩子有第二个参数，数据类型是 Array。</p>
<p><code>注意</code></p>
<ul>
<li>数组为空，代表不检测数据更新</li>
<li>数组中填写的变量，才会被检测更新</li>
<li>如果整个页面所有数据都需要检测更新，那么可以直接不写数组</li>
</ul>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; useEffect, useState &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> [num1, setNum1] = <span class="hljs-title function_">useState</span>(<span class="hljs-number">1</span>)<br>  <span class="hljs-keyword">const</span> [num2, setNum2] = <span class="hljs-title function_">useState</span>(<span class="hljs-number">1</span>)<br><br>  <span class="hljs-title function_">useEffect</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;num1更新了&#x27;</span>)<br>  &#125;, [num1])<br><br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>数字1:&#123;num1&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> setNum1(num1 + 1)&#125;&gt;累加num1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">hr</span> /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>数字2:&#123;num2&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> setNum2(num2 + 1)&#125;&gt;累加num1<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="3、createContext"><a href="#3、createContext" class="headerlink" title="3、createContext"></a>3、createContext</h4><p>函数式组件中，可以利用上下文空间 context 实现跨级组件传值。</p>
<h5 id="用法一：Provider-与-Consumer"><a href="#用法一：Provider-与-Consumer" class="headerlink" title="用法一：Provider 与 Consumer"></a>用法一：Provider 与 Consumer</h5><p>通过 createContext 创建的上下文空间自带 Provider(提供器)与 Consumer(接收器)，具体用法如下：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; createContext &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">const</span> <span class="hljs-title class_">MsgContext</span> = <span class="hljs-title function_">createContext</span>()<br><br><span class="hljs-comment">// 子组件</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Sub</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">MsgContext.Consumer</span>&gt;</span></span><br><span class="language-xml">      &#123;(&#123; msg &#125;) =&gt; <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>子组件：&#123;msg&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>&#125;</span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">MsgContext.Consumer</span>&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-comment">// 父组件</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Father</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Sub</span> /&gt;</span></span><br>&#125;<br><br><span class="hljs-comment">// 顶级组件</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">MsgContext.Provider</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&#123;&#123;</span> <span class="hljs-attr">msg:</span> &#x27;<span class="hljs-attr">你好世界</span>&#x27; &#125;&#125;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">Father</span> /&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">MsgContext.Provider</span>&gt;</span></span><br>  )<br>&#125;<br></code></pre></td></tr></table></figure>

<h5 id="用法二：useContext"><a href="#用法二：useContext" class="headerlink" title="用法二：useContext"></a>用法二：useContext</h5><p>上下文空间创建后，子组件也可以使用 useContext 这个 Hook 调用上下文空间。</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; createContext, useContext &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">const</span> <span class="hljs-title class_">MsgContext</span> = <span class="hljs-title function_">createContext</span>()<br><br><span class="hljs-comment">// 子组件</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Sub</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> &#123; msg &#125; = <span class="hljs-title function_">useContext</span>(<span class="hljs-title class_">MsgContext</span>) <span class="hljs-comment">// 使用useContext调用上下文空间</span><br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>子组件：&#123;msg&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br>&#125;<br><br><span class="hljs-comment">// 父组件</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Father</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Sub</span> /&gt;</span></span><br>&#125;<br><br><span class="hljs-comment">// 顶级组件</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">MsgContext.Provider</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&#123;&#123;</span> <span class="hljs-attr">msg:</span> &#x27;<span class="hljs-attr">你好世界</span>&#x27; &#125;&#125;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">Father</span> /&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">MsgContext.Provider</span>&gt;</span></span><br>  )<br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="4、useRef"><a href="#4、useRef" class="headerlink" title="4、useRef"></a>4、useRef</h4><p>使用 useRef 可以获取某个组件或元素：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; useRef &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> element = <span class="hljs-title function_">useRef</span>(<span class="hljs-literal">null</span>)<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">&#123;element&#125;</span> /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> console.log(element.current.value)&#125;&gt;</span><br><span class="language-xml">        获取input的值</span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br></code></pre></td></tr></table></figure>

<p><code>补充：React中表单元素包含受控组件与不受控组件</code></p>
<h5 id="不受控组件"><a href="#不受控组件" class="headerlink" title="不受控组件"></a>不受控组件</h5><p>不受控组件代表表单元素的值不受 state 控制，那么获取表单元素的值便只能通过 ref 获取（函数式组件中使用 useRef 获取，用法如以上代码）。</p>
<h5 id="受控组件"><a href="#受控组件" class="headerlink" title="受控组件"></a>受控组件</h5><p>受控组件代表表单元素的值受 state 控制（函数式组件中可以理解为受 useState 控制），获取其值时直接通过 state 获取即可：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; useState &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> [msg, setMsg] = <span class="hljs-title function_">useState</span>(<span class="hljs-string">&#x27;&#x27;</span>)<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;text&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&#123;msg&#125;</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">&#123;(e)</span> =&gt;</span> setMsg(e.target.value)&#125; /&gt;</span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> console.log(msg)&#125;&gt;获取input的值<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="5、memo"><a href="#5、memo" class="headerlink" title="5、memo"></a>5、memo</h4><p>实际开发中，我们会意识到一个现象：当父组件更新时，子组件会被迫更新。</p>
<p>这就导致性能损耗，来看以下代码：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; useState &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-comment">// 子组件</span><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">Sub</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;子组件被更新了&#x27;</span>)<br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>子组件<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>&#125;<br><br><span class="hljs-comment">// 父组件</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> [msg, setMsg] = <span class="hljs-title function_">useState</span>(<span class="hljs-string">&#x27;你好世界&#x27;</span>)<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>内容为：&#123;msg&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> setMsg(&#x27;Hello World&#x27;)&#125;&gt;修改Msg<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">hr</span> /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">Sub</span> /&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br></code></pre></td></tr></table></figure>

<p>此时，我们需要借助 memo 这个 hook 来缓存 Sub 组件，避免它被强制更新：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; useState, memo &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-comment">// 子组件</span><br><span class="hljs-keyword">const</span> <span class="hljs-title class_">Sub</span> = <span class="hljs-title function_">memo</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;子组件被更新了&#x27;</span>)<br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>子组件<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><br>&#125;)<br><br><span class="hljs-comment">// 父组件</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> [msg, setMsg] = <span class="hljs-title function_">useState</span>(<span class="hljs-string">&#x27;你好世界&#x27;</span>)<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>内容为：&#123;msg&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;()</span> =&gt;</span> setMsg(&#x27;Hello World&#x27;)&#125;&gt;修改Msg<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">hr</span> /&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">Sub</span> /&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="6、useMemo-与-useCallback"><a href="#6、useMemo-与-useCallback" class="headerlink" title="6、useMemo 与 useCallback"></a>6、useMemo 与 useCallback</h4><h5 id="useCallback"><a href="#useCallback" class="headerlink" title="useCallback"></a>useCallback</h5><p>当把触发 msg 修改的按钮放到子组件后，msg 一修改又会触发 Sub 的更新：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123; useState, memo &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><br><span class="hljs-comment">// 子组件</span><br><span class="hljs-keyword">const</span> <span class="hljs-title class_">Sub</span> = <span class="hljs-title function_">memo</span>(<span class="hljs-function">(<span class="hljs-params">props</span>) =&gt;</span> &#123;<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;子组件被更新了&#x27;</span>)<br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;props.mySetMsg&#125;</span>&gt;</span>修改Msg<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br>&#125;)<br><br><span class="hljs-comment">// 父组件</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> [msg, setMsg] = <span class="hljs-title function_">useState</span>(<span class="hljs-string">&#x27;你好世界&#x27;</span>)<br><br>  <span class="hljs-keyword">const</span> <span class="hljs-title function_">mySetMsg</span> = (<span class="hljs-params"></span>) =&gt; <span class="hljs-title function_">setMsg</span>(<span class="hljs-string">&#x27;Hello World&#x27;</span>)<br><br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>内容为：&#123;msg&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">Sub</span> <span class="hljs-attr">mySetMsg</span>=<span class="hljs-string">&#123;mySetMsg&#125;</span> /&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br></code></pre></td></tr></table></figure>

<p>此时，只要给 mySetMsg 方法套上 useCallback 即可：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">const</span> mySetMsg = <span class="hljs-title function_">useCallback</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-title function_">setMsg</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-string">&#x27;Hello World&#x27;</span>), []) <span class="hljs-comment">// 此处setMsg()中需要使用callback形式</span><br></code></pre></td></tr></table></figure>

<h5 id="useMemo"><a href="#useMemo" class="headerlink" title="useMemo"></a>useMemo</h5><p>useMemo 与 useCallback 差不多，只是 useMemo 需要在回调函数中再返回一个函数，我们称之为高阶函数：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">const</span> mySetMsg = <span class="hljs-title function_">useMemo</span>(<span class="hljs-function">() =&gt;</span> &#123;<br>  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-title function_">setMsg</span>(<span class="hljs-string">&#x27;Hello World&#x27;</span>)<br>&#125;, [])<br></code></pre></td></tr></table></figure>

<h2 id="状态管理工具-React-Redux"><a href="#状态管理工具-React-Redux" class="headerlink" title="状态管理工具 React Redux"></a>状态管理工具 React Redux</h2><h3 id="一、React-Redux-简介"><a href="#一、React-Redux-简介" class="headerlink" title="一、React Redux 简介"></a>一、React Redux 简介</h3><p>React Redux 是专门针对 React 所设计的<strong>状态管理工具</strong>。</p>
<p><img src="https://files.catbox.moe/wmmkte.png" srcset="/img/loading.gif" lazyload></p>
<h3 id="二、安装与仓库创建"><a href="#二、安装与仓库创建" class="headerlink" title="二、安装与仓库创建"></a>二、安装与仓库创建</h3><h4 id="1、安装"><a href="#1、安装" class="headerlink" title="1、安装"></a>1、安装</h4><p>React Redux 基于 Redux，因此安装时需要两者一起安装：</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stylus">$ npm <span class="hljs-selector-tag">i</span> redux react-redux <span class="hljs-attr">--save</span><br></code></pre></td></tr></table></figure>

<h4 id="2、仓库创建"><a href="#2、仓库创建" class="headerlink" title="2、仓库创建"></a>2、仓库创建</h4><p>在 src 下，创建 store 目录，包含 reducer.js 以及 index.js。</p>
<p><code>reducer.js</code></p>
<p>这个文件用于定义默认数据，并导出一个函数：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// 定义默认数据</span><br><span class="hljs-keyword">const</span> defaultState = &#123;<br>  <span class="hljs-attr">msg</span>: <span class="hljs-string">&#x27;你好世界&#x27;</span>,<br>&#125;<br><br><span class="hljs-comment">// 导出一个函数</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> (state = defaultState, action) =&gt; &#123;<br>  <span class="hljs-keyword">return</span> state<br>&#125;<br></code></pre></td></tr></table></figure>

<p><code>store&gt;index.js</code></p>
<p>这个文件主要是创建仓库、引用 reducer，并导出 store：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> reducer <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./reducer&#x27;</span><br><span class="hljs-keyword">import</span> &#123; createStore &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;redux&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> store = <span class="hljs-title function_">createStore</span>(reducer)<br></code></pre></td></tr></table></figure>

<h3 id="三、提供器与连接器"><a href="#三、提供器与连接器" class="headerlink" title="三、提供器与连接器"></a>三、提供器与连接器</h3><h4 id="1、提供器"><a href="#1、提供器" class="headerlink" title="1、提供器"></a>1、提供器</h4><p>找到顶级组件的外层，如在入口文件 index.js 中：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">ReactDOM</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-dom&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./App&#x27;</span><br><span class="hljs-keyword">import</span> &#123; store &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./store&#x27;</span><br><span class="hljs-keyword">import</span> &#123; <span class="hljs-title class_">Provider</span> &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-redux&#x27;</span><br><br><span class="hljs-title class_">ReactDOM</span>.<span class="hljs-title function_">render</span>(<br>  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">store</span>=<span class="hljs-string">&#123;store&#125;</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span></span><br><span class="language-xml">  <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>,<br>  <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;root&#x27;</span>)<br>)<br></code></pre></td></tr></table></figure>

<h4 id="2、连接器"><a href="#2、连接器" class="headerlink" title="2、连接器"></a>2、连接器</h4><p>在需要调用数据的组件中使用连接器：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> &#123; connect &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-redux&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params">props</span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>&#123;props.msg&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-comment">// state映射</span><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">mapStateToProps</span> = (<span class="hljs-params">state</span>) =&gt; &#123;<br>  <span class="hljs-keyword">return</span> &#123;<br>    <span class="hljs-attr">msg</span>: state.<span class="hljs-property">msg</span>,<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title function_">connect</span>(mapStateToProps)(<span class="hljs-title class_">App</span>)<br></code></pre></td></tr></table></figure>

<p>这里注意连接器的格式：</p>
<figure class="highlight pf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pf">connect(<span class="hljs-keyword">state</span>映射, dispatch映射)(当前组件类)<br></code></pre></td></tr></table></figure>

<h3 id="四、事件"><a href="#四、事件" class="headerlink" title="四、事件"></a>四、事件</h3><h4 id="1、创建修改-msg-的函数"><a href="#1、创建修改-msg-的函数" class="headerlink" title="1、创建修改 msg 的函数"></a>1、创建修改 msg 的函数</h4><p>如果需要修改 msg，那么需要在 reducer.js 导出的函数中定义：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// 定义默认数据</span><br><span class="hljs-keyword">const</span> defaultState = &#123;<br>  <span class="hljs-attr">msg</span>: <span class="hljs-string">&#x27;你好世界&#x27;</span>,<br>&#125;<br><br><span class="hljs-comment">// 导出一个函数</span><br><span class="hljs-comment">// eslint-disable-next-line</span><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> (state = defaultState, action) =&gt; &#123;<br>  <span class="hljs-keyword">let</span> newState = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(<span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(state))<br>  <span class="hljs-keyword">switch</span> (action.<span class="hljs-property">type</span>) &#123;<br>    <span class="hljs-keyword">case</span> <span class="hljs-string">&#x27;changeMsg&#x27;</span>:<br>      newState.<span class="hljs-property">msg</span> = action.<span class="hljs-property">value</span><br>      <span class="hljs-keyword">break</span><br>    <span class="hljs-attr">default</span>:<br>      <span class="hljs-keyword">break</span><br>  &#125;<br>  <span class="hljs-keyword">return</span> newState<br>&#125;<br></code></pre></td></tr></table></figure>

<p><code>注意：action.type就是组件在调用方法时需要传入的函数名称，action.value则是调用方法时携带的参数。</code></p>
<h4 id="2、调用修改-msg-的函数"><a href="#2、调用修改-msg-的函数" class="headerlink" title="2、调用修改 msg 的函数"></a>2、调用修改 msg 的函数</h4><p>在组件中：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> &#123; connect &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-redux&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params">props</span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>&#123;props.msg&#125;<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">&#123;props.changeMsgFn&#125;</span>&gt;</span>修改msg<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-comment">// ..省略了状态映射的代码</span><br><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">mapDispatchToProps</span> = (<span class="hljs-params">dispatch</span>) =&gt; &#123;<br>  <span class="hljs-keyword">return</span> &#123;<br>    <span class="hljs-title function_">changeMsgFn</span>(<span class="hljs-params"></span>) &#123;<br>      <span class="hljs-keyword">let</span> action = &#123; <span class="hljs-attr">type</span>: <span class="hljs-string">&#x27;changeMsg&#x27;</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">&#x27;hello world&#x27;</span> &#125;<br>      <span class="hljs-title function_">dispatch</span>(action)<br>    &#125;,<br>  &#125;<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title function_">connect</span>(mapStateToProps, mapDispatchToProps)(<span class="hljs-title class_">App</span>)<br></code></pre></td></tr></table></figure>

<h2 id="路由"><a href="#路由" class="headerlink" title="路由"></a>路由</h2><h3 id="一、安装"><a href="#一、安装" class="headerlink" title="一、安装"></a>一、安装</h3><p>React 有自己的一套路由（router-router-dom）</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs jsx">yarn add react-router-dom@<span class="hljs-number">6</span><br></code></pre></td></tr></table></figure>

<h3 id="二、路由文件"><a href="#二、路由文件" class="headerlink" title="二、路由文件"></a>二、路由文件</h3><h4 id="1、创建若干页面"><a href="#1、创建若干页面" class="headerlink" title="1、创建若干页面"></a>1、创建若干页面</h4><p>在 src 下创建 pages 目录，并在其中创建 Home.jsx、List.jsx 和 Detail.jsx 等页面。</p>
<h4 id="2、创建路由组件"><a href="#2、创建路由组件" class="headerlink" title="2、创建路由组件"></a>2、创建路由组件</h4><p>src 下创建 router 目录，并在其中创建 index.jsx</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> &#123; <span class="hljs-title class_">BrowserRouter</span>, <span class="hljs-title class_">Route</span>, <span class="hljs-title class_">Routes</span> &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-router-dom&#x27;</span><br><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">App</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../App&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">Home</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../pages/Home&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">List</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../pages/List&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">Detail</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../pages/Detail&#x27;</span><br><br><span class="hljs-keyword">const</span> <span class="hljs-title function_">BaseRouter</span> = (<span class="hljs-params"></span>) =&gt; (<br>  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">BrowserRouter</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;<span class="hljs-name">Routes</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">&quot;/&quot;</span> <span class="hljs-attr">element</span>=<span class="hljs-string">&#123;</span>&lt;<span class="hljs-attr">App</span> /&gt;</span>&#125;&gt;</span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">&quot;/home&quot;</span> <span class="hljs-attr">element</span>=<span class="hljs-string">&#123;</span>&lt;<span class="hljs-attr">Home</span> /&gt;</span>&#125;&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">&quot;/list&quot;</span> <span class="hljs-attr">element</span>=<span class="hljs-string">&#123;</span>&lt;<span class="hljs-attr">List</span> /&gt;</span>&#125;&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">&quot;/detail&quot;</span> <span class="hljs-attr">element</span>=<span class="hljs-string">&#123;</span>&lt;<span class="hljs-attr">Detail</span> /&gt;</span>&#125;&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/<span class="hljs-name">Routes</span>&gt;</span></span><br><span class="language-xml">  <span class="hljs-tag">&lt;/<span class="hljs-name">BrowserRouter</span>&gt;</span></span><br>)<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">BaseRouter</span><br></code></pre></td></tr></table></figure>

<h4 id="3、入口文件调用路由组件"><a href="#3、入口文件调用路由组件" class="headerlink" title="3、入口文件调用路由组件"></a>3、入口文件调用路由组件</h4><p>在入口文件中，移除对 App.jsx 的调用，改为：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">ReactDOM</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-dom&#x27;</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">Router</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./router/index.jsx&#x27;</span><br><br><span class="hljs-title class_">ReactDOM</span>.<span class="hljs-title function_">render</span>(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Router</span> /&gt;</span></span>, <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">getElementById</span>(<span class="hljs-string">&#x27;root&#x27;</span>))<br></code></pre></td></tr></table></figure>

<h4 id="4、Outlet"><a href="#4、Outlet" class="headerlink" title="4、Outlet"></a>4、Outlet</h4><p>在 App.jsx 中，使用 Outlet 来展示子路由：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> &#123; <span class="hljs-title class_">Outlet</span> &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-router-dom&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">Outlet</span> /&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>

<p>如此，便可在浏览器地址栏中通过 url 的切换实现不同路由对应的组件展示。</p>
<h3 id="三、跳转"><a href="#三、跳转" class="headerlink" title="三、跳转"></a>三、跳转</h3><h4 id="1、Link-标签"><a href="#1、Link-标签" class="headerlink" title="1、Link 标签"></a>1、Link 标签</h4><p>原生 JS 中的 a 标签，在 react-router-dom 中使用 Link 标签代替：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> &#123; <span class="hljs-title class_">Outlet</span>, <span class="hljs-title class_">Link</span> &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-router-dom&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">return</span> (<br>    <span class="language-xml"><span class="hljs-tag">&lt;&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml">          <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">&quot;/home&quot;</span>&gt;</span>首页<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml">          <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">&quot;/list&quot;</span>&gt;</span>列表页<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml">          <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">&quot;/detail&quot;</span>&gt;</span>详情页<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span></span><br><span class="language-xml">        <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span></span><br><span class="language-xml">      <span class="hljs-tag">&lt;<span class="hljs-name">Outlet</span> /&gt;</span></span><br><span class="language-xml">    <span class="hljs-tag">&lt;/&gt;</span></span><br>  )<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>

<h4 id="2、useLocation"><a href="#2、useLocation" class="headerlink" title="2、useLocation"></a>2、useLocation</h4><p>使用 useLocation 这个路由 hook，可以获取地址栏路径：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> &#123; useLocation &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-router-dom&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">let</span> &#123; pathname &#125; = <span class="hljs-title function_">useLocation</span>() <span class="hljs-comment">// 得到当前路径</span><br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="3、navigate"><a href="#3、navigate" class="headerlink" title="3、navigate"></a>3、navigate</h4><p>使用 useNavigate 这个路由 hook，可以实现路由跳转。若要判断这个路径如果为/，则自动跳转到/home，代码如下：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span>, &#123;useEffect&#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> &#123;<span class="hljs-title class_">Outlet</span>, <span class="hljs-title class_">Link</span>, useLocation, useNavigate&#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-router-dom&#x27;</span><br><br><span class="hljs-keyword">function</span> <span class="hljs-title function_">App</span>(<span class="hljs-params"></span>) &#123;<br>    <span class="hljs-keyword">let</span> &#123;pathname&#125; = <span class="hljs-title function_">useLocation</span>()<br>    <span class="hljs-keyword">const</span> navigate = <span class="hljs-title function_">useNavigate</span>()<br><br>    <span class="hljs-title function_">useEffect</span>(<span class="hljs-function">()=&gt;</span>&#123;<br>        <span class="hljs-keyword">if</span>(pathname===<span class="hljs-string">&#x27;/&#x27;</span>)&#123;<br>            <span class="hljs-title function_">navigate</span>(<span class="hljs-string">&#x27;/home&#x27;</span>)<br>        &#125;<br>    &#125;, [])<br><br>    <span class="hljs-keyword">return</span> ...<br>&#125;<br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-title class_">App</span><br></code></pre></td></tr></table></figure>

<h3 id="四、参数携带"><a href="#四、参数携带" class="headerlink" title="四、参数携带"></a>四、参数携带</h3><h4 id="1、url-子路由形式"><a href="#1、url-子路由形式" class="headerlink" title="1、url 子路由形式"></a>1、url 子路由形式</h4><p>通过在路由中配置子路由形式，可以实现参数传递。如给/list 携带参数，以这个形式：/list/123。</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// 路由文件</span><br>&lt;<span class="hljs-title class_">Route</span> path=<span class="hljs-string">&#x27;/list/:id&#x27;</span> element=&#123;<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">List</span> /&gt;</span></span>&#125;&gt;&lt;/<span class="hljs-title class_">Route</span>&gt;<br><br><span class="hljs-comment">// App.jsx中</span><br><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">&quot;/list/123&quot;</span>&gt;</span>列表页<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span><br></code></pre></td></tr></table></figure>

<p>如果想要获取参数的值，可以使用 useParams 这个路由 hook：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> &#123; useParams &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-router-dom&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">List</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> params = <span class="hljs-title function_">useParams</span>()<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(params) <span class="hljs-comment">// &#123;id: &#x27;123&#x27;&#125;</span><br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>List列表页<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="2、问号-形式"><a href="#2、问号-形式" class="headerlink" title="2、问号?形式"></a>2、问号?形式</h4><p>地址栏携带参数还可以通过问号形式：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs jsx">&lt;li&gt;<br>  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">&quot;/detail?id=456&quot;</span>&gt;</span>详情页<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span></span><br>&lt;/li&gt;<br></code></pre></td></tr></table></figure>

<p>获取该参数的方式，需要使用 useSearchParams 这个路由 hook，并且调用 getAll 方法才能获取得到：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> &#123; useSearchParams &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-router-dom&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">Detail</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> [params] = <span class="hljs-title function_">useSearchParams</span>()<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(params.<span class="hljs-title function_">getAll</span>(<span class="hljs-string">&#x27;id&#x27;</span>)) <span class="hljs-comment">// [&#x27;456&#x27;]</span><br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Detail详情页<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br>&#125;<br></code></pre></td></tr></table></figure>

<h4 id="3、state-携带"><a href="#3、state-携带" class="headerlink" title="3、state 携带"></a>3、state 携带</h4><p>以上两种携带参数的方式，都只能携带简单的参数，如果数据量较大，其实并不方便，因此，在使用 useNavigate()这个 hook 实现跳转时，其实也可以携带参数：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-title function_">navigate</span>(<span class="hljs-string">&#x27;/home&#x27;</span>, &#123;<br>  <span class="hljs-attr">state</span>: &#123; <span class="hljs-attr">id</span>: <span class="hljs-number">789</span> &#125;,<br>&#125;)<br></code></pre></td></tr></table></figure>

<p>获取该参数的方式便是使用 useLocation 这个路由 hook：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-keyword">import</span> <span class="hljs-title class_">React</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react&#x27;</span><br><span class="hljs-keyword">import</span> &#123; useLocation &#125; <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;react-router-dom&#x27;</span><br><br><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">Home</span>(<span class="hljs-params"></span>) &#123;<br>  <span class="hljs-keyword">const</span> location = <span class="hljs-title function_">useLocation</span>()<br>  <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(location.<span class="hljs-property">state</span>.<span class="hljs-property">id</span>) <span class="hljs-comment">// 789</span><br>  <span class="hljs-keyword">return</span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Home首页<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span></span><br>&#125;<br></code></pre></td></tr></table></figure>

<h3 id="五、404-匹配"><a href="#五、404-匹配" class="headerlink" title="五、404 匹配"></a>五、404 匹配</h3><p>如果碰上未在路由文件中有做配置的路由，便可认定为 404 页面：</p>
<figure class="highlight jsx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs jsx"><span class="hljs-comment">// 路由组件</span><br><span class="hljs-keyword">import</span> <span class="hljs-title class_">Error</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;../pages/Error&#x27;</span><br>;<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">&quot;/&quot;</span> <span class="hljs-attr">element</span>=<span class="hljs-string">&#123;</span>&lt;<span class="hljs-attr">App</span> /&gt;</span>&#125;&gt;</span><br><span class="language-xml">  ...省略部分路由内容</span><br><span class="language-xml">  <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">&quot;*&quot;</span> <span class="hljs-attr">element</span>=<span class="hljs-string">&#123;</span>&lt;<span class="hljs-attr">Error</span> /&gt;</span>&#125;&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span></span><br><span class="language-xml"><span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span></span><br></code></pre></td></tr></table></figure>

<p>此时只要是非配置过的页面，便是 404 页面。</p>

                
              </div>
            
            <hr/>
            <div>
              <div class="post-metas my-3">
  
    <div class="post-meta mr-3 d-flex align-items-center">
      <i class="iconfont icon-category"></i>
      

<span class="category-chains">
  
  
    
      <span class="category-chain">
        
  <a href="/categories/%E5%89%8D%E7%AB%AF/" class="category-chain-item">前端</a>
  
  

      </span>
    
  
</span>

    </div>
  
  
    <div class="post-meta">
      <i class="iconfont icon-tags"></i>
      
        <a href="/tags/react/">#react</a>
      
    </div>
  
</div>


              
  

  <div class="license-box my-3">
    <div class="license-title">
      <div>react学习笔记</div>
      <div>http://dayu.com/2022/11/27/react学习笔记/</div>
    </div>
    <div class="license-meta">
      
        <div class="license-meta-item">
          <div>作者</div>
          <div>dayu</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>发布于</div>
          <div>2022年11月27日</div>
        </div>
      
      
      
        <div class="license-meta-item">
          <div>许可协议</div>
          <div>
            
              
              
                <a target="_blank" href="https://creativecommons.org/licenses/by/4.0/">
                  <span class="hint--top hint--rounded" aria-label="BY - 署名">
                    <i class="iconfont icon-by"></i>
                  </span>
                </a>
              
            
          </div>
        </div>
      
    </div>
    <div class="license-icon iconfont"></div>
  </div>



              
                <div class="post-prevnext my-3">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2022/11/30/HeadLine/" title="HeadLine">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">HeadLine</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2022/11/23/node%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" title="node学习笔记">
                        <span class="hidden-mobile">node学习笔记</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
  <article id="comments" lazyload>
    
  <div id="valine"></div>
  <script type="text/javascript">
    Fluid.utils.loadComments('#valine', function() {
      Fluid.utils.createScript('https://lib.baomitu.com/valine/1.5.1/Valine.min.js', function() {
        var options = Object.assign(
          {"appId":"你的appId","appKey":"你的appKey","path":"window.location.pathname","placeholder":"留言仅限讨论，禁止广告等行为","avatar":"retro","meta":["nick","mail","link"],"requiredFields":[],"pageSize":10,"lang":"zh-CN","highlight":false,"recordIP":false,"serverURLs":"你的serverURLs","emojiCDN":null,"emojiMaps":null,"enableQQ":false},
          {
            el: "#valine",
            path: window.location.pathname
          }
        )
        new Valine(options);
        Fluid.utils.waitElementVisible('#valine .vcontent', () => {
          var imgSelector = '#valine .vcontent img:not(.vemoji)';
          Fluid.plugins.imageCaption(imgSelector);
          Fluid.plugins.fancyBox(imgSelector);
        })
      });
    });
  </script>
  <noscript>Please enable JavaScript to view the comments</noscript>


  </article>


          </article>
        </div>
      </div>
    </div>

    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar" style="margin-left: -1rem">
    <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>



  </aside>


    </div>
  </div>
</div>





  



  



  



  



  







    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v" for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>

    

    
  </main>

  <footer>
    <div class="footer-inner">
  
    <div class="footer-content">
       <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
    </div>
  
  
    <div class="statistics">
  
  

  
    
      <span id="busuanzi_container_site_pv" style="display: none">
        总访问量 
        <span id="busuanzi_value_site_pv"></span>
         次
      </span>
    
    
      <span id="busuanzi_container_site_uv" style="display: none">
        总访客数 
        <span id="busuanzi_value_site_uv"></span>
         人
      </span>
    
    
  
</div>

  
  
  
</div>

  </footer>

  <!-- Scripts -->
  
  <script  src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js" ></script>
<script  src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>


  <script  src="https://lib.baomitu.com/typed.js/2.0.12/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var subtitle = document.getElementById('subtitle');
      if (!subtitle || !typing) {
        return;
      }
      var text = subtitle.getAttribute('data-typed-text');
      
        typing(text);
      
    })(window, document);
  </script>




  
    <script  src="/js/img-lazyload.js" ></script>
  




  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.18.2/tocbot.min.js', function() {
    var toc = jQuery('#toc');
    if (toc.length === 0 || !window.tocbot) { return; }
    var boardCtn = jQuery('#board-ctn');
    var boardTop = boardCtn.offset().top;

    window.tocbot.init(Object.assign({
      tocSelector     : '#toc-body',
      contentSelector : '.markdown-body',
      linkClass       : 'tocbot-link',
      activeLinkClass : 'tocbot-active-link',
      listClass       : 'tocbot-list',
      isCollapsedClass: 'tocbot-is-collapsed',
      collapsibleClass: 'tocbot-is-collapsible',
      scrollSmooth    : true,
      includeTitleTags: true,
      headingsOffset  : -boardTop,
    }, CONFIG.toc));
    if (toc.find('.toc-list-item').length > 0) {
      toc.css('visibility', 'visible');
    }

    Fluid.events.registerRefreshCallback(function() {
      if ('tocbot' in window) {
        tocbot.refresh();
        var toc = jQuery('#toc');
        if (toc.length === 0 || !tocbot) {
          return;
        }
        if (toc.find('.toc-list-item').length > 0) {
          toc.css('visibility', 'visible');
        }
      }
    });
  });
</script>


  <script src=https://lib.baomitu.com/clipboard.js/2.0.11/clipboard.min.js></script>

  <script>Fluid.plugins.codeWidget();</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() {
    window.anchors.options = {
      placement: CONFIG.anchorjs.placement,
      visible  : CONFIG.anchorjs.visible
    };
    if (CONFIG.anchorjs.icon) {
      window.anchors.options.icon = CONFIG.anchorjs.icon;
    }
    var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
    var res = [];
    for (var item of el) {
      res.push('.markdown-body > ' + item.trim());
    }
    if (CONFIG.anchorjs.placement === 'left') {
      window.anchors.options.class = 'anchorjs-link-left';
    }
    window.anchors.add(res.join(', '));

    Fluid.events.registerRefreshCallback(function() {
      if ('anchors' in window) {
        anchors.removeAll();
        var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
        var res = [];
        for (var item of el) {
          res.push('.markdown-body > ' + item.trim());
        }
        if (CONFIG.anchorjs.placement === 'left') {
          anchors.options.class = 'anchorjs-link-left';
        }
        anchors.add(res.join(', '));
      }
    });
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() {
    Fluid.plugins.fancyBox();
  });
</script>


  <script>Fluid.plugins.imageCaption();</script>

  <script  src="/js/local-search.js" ></script>

  <script defer src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" ></script>




  
<script src="//cdn.jsdelivr.net/gh/bynotes/texiao/source/js/love.js"></script>
<script src="//cdn.jsdelivr.net/gh/bynotes/texiao/source/js/xiaoxingxing.js"></script>
<script src="//cdn.jsdelivr.net/gh/bynotes/texiao/source/js/xiaoxuehua.js"></script>
<script src="//cdn.jsdelivr.net/gh/bynotes/texiao/source/js/caidai.js"></script>



<!-- 主题的启动项，将它保持在最底部 -->
<!-- the boot of the theme, keep it at the bottom -->
<script  src="/js/boot.js" ></script>


  

  <noscript>
    <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div>
  </noscript>
</body>
</html>
